/**
*****************************************************************************
 * @file dev_adg1404.c
 * @brief ADG1404驱动
 * @author luffy
 * @version V1.0.0
 * @date 2022/11/30
****************************************************************************
 */
#include "FreeRTOS.h"
#include "dev_adg1404.h"
#include "semphr.h"
/* Private Struct ---------------------------------------------------------------*/
drv_adg1404_t adg1404 = 
{
	.PIN_A0 = "D8",
	.PIN_A1 = "D9",
};

typedef struct 
{
    GPIO_TypeDef       *GPIOx;
    uint16_t           PINx;
}adg1404_config_t;

static const adg1404_config_t adg1404_conf_list[PIN_NUM] = {
    {GPIOD,    GPIO_Pin_8},
    {GPIOD,    GPIO_Pin_9},
};
	
/* Private defines ---------------------------------------------------------------*/

/* Private enum ---------------------------------------------------------------*/
	
/* Private Variable ---------------------------------------------------------------*/
static uint8_t  s_bInitialized = false;     // 标识驱动程序模块是否已经初始化

static SemaphoreHandle_t ADG1404_Sem;
//Pointer
//Array
//Const
/* Private function prototypes -----------------------------------------------*/
/*****************************************************************************
* @brief ADG1404驱动初始化
* ex:
* @par 
* None
* @retval 
*****************************************************************************/
int Dev_Adg1404_init(drv_adg1404_t *this)
{
	if(s_bInitialized)
    {
        return 0;
    }
	
	this->private.A0.PIN = this->PIN_A0;    
	this->private.A0.MODE = OUTPUT_DOWN;             
	this->private.A0.INIT_LEVEL = LOW_LEVEL;      
	if (Drv_Gpio_Init(&this->private.A0) < 0) 
	{                                              
		return -1;                                 
	}
	
	this->private.A1.PIN = this->PIN_A1;    
	this->private.A1.MODE = OUTPUT_DOWN;             
	this->private.A1.INIT_LEVEL = LOW_LEVEL;      
	if (Drv_Gpio_Init(&this->private.A1) < 0) 
	{                                              
		return -1;                                 
	}
	
	s_bInitialized = true;
	
	ADG1404_Sem = xSemaphoreCreateMutex();
	
	return 0;
}

/*****************************************************************************
* @brief ADG1404通道选择
* ex:
* @par ch:通道（ADG1404_S1，ADG1404_S2，ADG1404_S3，ADG1404_S4）
* None
* @retval 
*****************************************************************************/
void ADG1404_ON_CH(adg1404_source_pin_e ch)
{
	if(!s_bInitialized)
    {
        Dev_Adg1404_init(&adg1404);
    }
	
	xSemaphoreTake(ADG1404_Sem, portMAX_DELAY); //多任务互斥保护
	
    switch (ch)
    {
		case ADG1404_S1:
			GPIO_ResetBits(adg1404_conf_list[A0].GPIOx, adg1404_conf_list[A0].PINx);
			GPIO_ResetBits(adg1404_conf_list[A1].GPIOx, adg1404_conf_list[A1].PINx);
			break;
		case ADG1404_S2:
			GPIO_SetBits(adg1404_conf_list[A0].GPIOx, adg1404_conf_list[A0].PINx);
			GPIO_ResetBits(adg1404_conf_list[A1].GPIOx, adg1404_conf_list[A1].PINx);
			break;
		case ADG1404_S3:
			GPIO_ResetBits(adg1404_conf_list[A0].GPIOx, adg1404_conf_list[A0].PINx);
			GPIO_SetBits(adg1404_conf_list[A1].GPIOx, adg1404_conf_list[A1].PINx);
			break;
		case ADG1404_S4:
			GPIO_SetBits(adg1404_conf_list[A0].GPIOx, adg1404_conf_list[A0].PINx);
			GPIO_SetBits(adg1404_conf_list[A1].GPIOx, adg1404_conf_list[A1].PINx);
			break;
		default:
			break;
    }
	
	xSemaphoreGive(ADG1404_Sem);
}
